 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SnmpSharpNet;
using System.IO;
using System.Windows.Forms;

namespace Thompson
{
    
    class Tx
    {
        /*****************************
         * Declare global enumerations
         *****************************/
        public enum E_Operator
        {
            LocalMode,
            RemoteWWW,
            Remote,
            Maintenance,
            Unknown
        }
        public enum E_SwitchOverMode
        {
            Unknown,
            Manual,
            Auto
        }
        public enum E_CommandTx
        {
            Unknown=0,
            GeneralShutdown,
            CoolingOn,
            HeatingOn,
            CircuitBreakerOn,
            GeneralOn 
            
        }
        public enum E_CommandModulationMode
        {
            DRM=0,  
            AM=16,
            DCC1=17,
            DCC2=18,
            DCC3=19,
            DCC4=20,
            AMC=21,
            EHC=22,
            SSB=31,
            SSB1=32,
            SSB2=42,
            SSB3=43,
            simulcast=96,
            simulcast_right=97,
            symetrical_simulcast=98,
            scs_right=112,
            scs_left=113,
            Unknown
        }
        public enum E_CommandPower
        {
            Unknown,
            PlusOne,        // plus 1%
            LessOne,        // less 1%
            NormalPower,    // normal (93% for sw250kw)
            ReducedPower,   // reuced (47% for sw250kw)
            OperatorPower,  // selectable value for sw250kw
            Maximum         // specific predefined value for sw500kw only
        }
        public enum E_Status
        {
				unknown=100,
				preheating=101,
				cooling_on=102,
				heating_on=103,
				hv_applied=104,
				minimal_power=105,
				transmitter_on=106,
				post_cooling=301,
				cooling_start=302,
				heating_start=303,
				cooling_in_fault=201,
				heating_in_fault=202,
				breaker_off=203,
				bias_off=204,
				medium_voltage_off=206,
				power_too_low=208,
				preheating_missing=209
    }

        /*******************************
         * Declare global properties
         *******************************/
        string txState = "unknown";
        public bool DisableUnknownStatusAlarm = false;
        
        //Create instance of log data for logging from this file
        AppMain.LogData log = new AppMain.LogData();

        //Read only Control properties from Function group
        public string IPaddress { get; set; }
        public bool CommEnabled { get; set; }
        TxItem TxNameObj = new TxItem { Description = "Transmitter name: ", Oid = ".1.3.6.1.4.1.8711.1.1.10.14.1.1.2.1.0", CurrentValue = "???", ReadOnly = true };
        TxItem SwitchOverModeObj = new TxItem { Description = "Adaptation: ", Oid = ".1.3.6.1.4.1.8711.1.1.10.14.1.1.2.11.0", CurrentValue = E_SwitchOverMode.Unknown, ReadOnly = true, RequestValue = E_SwitchOverMode.Auto };
        TxItem OperatorObj = new TxItem { Description = "Operation Mode: ", Oid = ".1.3.6.1.4.1.8711.1.1.10.14.1.1.2.12.0", CurrentValue = E_Operator.Unknown, ReadOnly = true, RequestValue = E_Operator.Remote };
        TxItem FrequencyNumberObj = new TxItem { Description = "Channel Number: ", Oid = ".1.3.6.1.4.1.8711.1.1.10.14.1.1.2.5.0", CurrentValue = (int)0, ReadOnly = true };
        TxItem ActualPowerPercentObj = new TxItem { Description = "Requested Power (%): ", Oid = ".1.3.6.1.4.1.8711.1.1.10.14.1.1.2.9.0", CurrentValue = (int)0, ReadOnly = true };
        TxItem GlobalStatusObj = new TxItem { Description = "Transmitter Status: ", Oid = ".1.3.6.1.4.1.8711.1.1.10.14.1.3.1.1.3.1", CurrentValue = (int)E_Status.unknown, ReadOnly = true };
        
        //Read-only properties from Measurement group
        TxItem MeasAudioInputLevelObj = new TxItem { Description = "Audio Input Level (%): ", Oid = ".1.3.6.1.4.1.8711.1.1.10.14.1.4.1.1.4.1.0", CurrentValue = (int)0, ReadOnly = true };
        TxItem MeasRfGridCurrentObj = new TxItem { Description = "RF Grid Current (x0.01 A): ", Oid = ".1.3.6.1.4.1.8711.1.1.10.14.1.4.1.1.4.1.1", CurrentValue = (int)0, ReadOnly = true };
        TxItem MeasRfGridVoltageObj = new TxItem { Description = "RF Grid Voltage (V): ", Oid = ".1.3.6.1.4.1.8711.1.1.10.14.1.4.1.1.4.1.2", CurrentValue = (int)0, ReadOnly = true };
        TxItem MeasRfPowerObj = new TxItem { Description = "RF Power (kW): ", Oid = ".1.3.6.1.4.1.8711.1.1.10.14.1.4.1.1.4.1.3", CurrentValue = (int)0, ReadOnly = true };
        TxItem MeasRfDifferentialTemperatureObj = new TxItem { Description = "RF Diff. Temp. (X 0.1 degrees): ", Oid = ".1.3.6.1.4.1.8711.1.1.10.14.1.4.1.1.4.1.4", CurrentValue = (int)0, ReadOnly = true };
        TxItem MeasRfAnodeCurrentObj = new TxItem { Description = "RF Anode Current (x0.1 A): ", Oid = ".1.3.6.1.4.1.8711.1.1.10.14.1.4.1.1.4.1.5", CurrentValue = (int)0, ReadOnly = true };
        TxItem MeasRfScreenCurrentObj = new TxItem { Description = "RF Screen Current (x0.01 A): ", Oid = ".1.3.6.1.4.1.8711.1.1.10.14.1.4.1.1.4.1.6", CurrentValue = (int)0, ReadOnly = true };
        TxItem MeasRfAnodeVoltageObj = new TxItem { Description = "RF Anode Voltage (x0.1 kV): ", Oid = ".1.3.6.1.4.1.8711.1.1.10.14.1.4.1.1.4.1.7", CurrentValue = (int)0, ReadOnly = true };
        TxItem MeasRfMainsVoltageObj = new TxItem { Description = "RF Mains Voltage (V): ", Oid = ".1.3.6.1.4.1.8711.1.1.10.14.1.4.1.1.4.1.8", CurrentValue = (int)0, ReadOnly = true };
        TxItem MeasVSWRObj = new TxItem { Description = "VSWR (x0.01): ", Oid = ".1.3.6.1.4.1.8711.1.1.10.14.1.4.1.1.4.1.9", CurrentValue = (int)0, ReadOnly = true };
        TxItem MeasReflectedPowerObj = new TxItem { Description = "Reflected Power (kW): ", Oid = ".1.3.6.1.4.1.8711.1.1.10.14.1.4.1.1.4.1.10", CurrentValue = (int)0, ReadOnly = true };
        
        //Command group properties
        TxItem CmdTxObj = new TxItem { Description = "Command TX Mode: ", Oid = ".1.3.6.1.4.1.8711.1.1.10.14.1.5.1.1.0", CurrentValue = E_CommandTx.Unknown };
        TxItem CmdModulationObj = new TxItem { Description = "Modulation Type: ", Oid = ".1.3.6.1.4.1.8711.1.1.10.14.1.5.1.101.1.0", CurrentValue = E_CommandModulationMode.Unknown };
        TxItem CmdPowerObj = new TxItem { Description = "Command Power Mode: ", Oid = ".1.3.6.1.4.1.8711.1.1.10.14.1.5.1.3.0", CurrentValue = E_CommandPower.Unknown, RequestValue = E_CommandPower.OperatorPower };
        TxItem PowerLevelObj = new TxItem { Description = "Command Power Level (%): ", Oid = ".1.3.6.1.4.1.8711.1.1.10.14.1.5.1.4.0", CurrentValue = (int)0 };
        TxItem CmdFreqNumObj = new TxItem { Description = "Command Channel Number: ", Oid = ".1.3.6.1.4.1.8711.1.1.10.14.1.5.1.12.0", CurrentValue = (int)0 };
        
        //Create new dictionary for collecting SNMP data
        Dictionary<string, TxItem> TxData = new Dictionary<string, TxItem>();
        
        public Tx()
        {
            //Add each TxItem to the dictionary
            TxData.Add(CmdTxObj.Oid, CmdTxObj);
            //TxData.Add(FrequencyNumberObj.Oid, FrequencyNumberObj);
            TxData.Add(CmdFreqNumObj.Oid, CmdFreqNumObj);
            TxData.Add(ActualPowerPercentObj.Oid, ActualPowerPercentObj);
            TxData.Add(CmdPowerObj.Oid, CmdPowerObj);
            TxData.Add(PowerLevelObj.Oid, PowerLevelObj);
            TxData.Add(CmdModulationObj.Oid, CmdModulationObj);
            TxData.Add(OperatorObj.Oid, OperatorObj);
            TxData.Add(SwitchOverModeObj.Oid, SwitchOverModeObj);
            TxData.Add(GlobalStatusObj.Oid, GlobalStatusObj);
            TxData.Add(MeasAudioInputLevelObj.Oid, MeasAudioInputLevelObj);
            TxData.Add(MeasReflectedPowerObj.Oid, MeasReflectedPowerObj);
            TxData.Add(MeasRfAnodeCurrentObj.Oid, MeasRfAnodeCurrentObj);
            TxData.Add(MeasRfAnodeVoltageObj.Oid, MeasRfAnodeVoltageObj);
            TxData.Add(MeasRfDifferentialTemperatureObj.Oid, MeasRfDifferentialTemperatureObj);
            TxData.Add(MeasRfGridCurrentObj.Oid, MeasRfGridCurrentObj);
            TxData.Add(MeasRfGridVoltageObj.Oid, MeasRfGridVoltageObj);
            TxData.Add(MeasRfMainsVoltageObj.Oid, MeasRfMainsVoltageObj);
            TxData.Add(MeasRfPowerObj.Oid, MeasRfPowerObj);
            TxData.Add(MeasRfScreenCurrentObj.Oid, MeasRfScreenCurrentObj);
            TxData.Add(MeasVSWRObj.Oid, MeasVSWRObj);
            TxData.Add(TxNameObj.Oid, TxNameObj);
        }

        /*************************************************
         * Begin SetValue methods
         *************************************************/
        public void SetFrequencyNumber (int newFrequencyNumber)
        {
            //Update the value
            int maxFreqNum = 16;
            int minFreqNum = 1;
            int setFreqNum;
            //Bound the new set Frequency
            if (newFrequencyNumber > maxFreqNum) setFreqNum = maxFreqNum;
            else if (newFrequencyNumber < minFreqNum) setFreqNum = minFreqNum;
            else setFreqNum = newFrequencyNumber;
            //Write the new Request value
            CmdFreqNumObj.RequestValue = setFreqNum;            // This item is the one the TX should respond to

        }
        public void SetCmdTx(E_CommandTx newCmdTx)
        {
            //Update the value
            CmdTxObj.RequestValue = newCmdTx;
        }
        public void SetCmdModulation (E_CommandModulationMode newCmdModulation)
        {
            //Update the values
            CmdModulationObj.RequestValue = newCmdModulation;
        }
        public void SetPowerLevel(int newPowerLevel)
        {
            //Update the value
            int maxPower = 99;
            int minPower = 20;
            int setPower;
            
            //Bound power to min/max values
            if (newPowerLevel > maxPower)
                setPower = maxPower;
            else if (newPowerLevel < minPower)
                setPower = minPower;
            else
                setPower = newPowerLevel;

            //Put the new value in the Request
            if (PowerLevelObj.RequestValue != setPower)
            {
                CmdPowerObj.RequestValue = E_CommandPower.OperatorPower;
                CmdPowerObj.CurrentValue = E_CommandPower.LessOne;  //Force a write of the CmdPowerObj to OperatorPower
                PowerLevelObj.RequestValue = setPower;              //For setting TX power. Current value is not the actual value.
                ActualPowerPercentObj.RequestValue = setPower;      //For alarm purposes and reading actual value
            }
       }

        public bool GetHeating()
        {
            //Public function returns true if Tx is heating
            string status = GetCurrentValue("GlobalStatusObj");
            if (
                (status[status.Length-1] >= 3) && 
                (status[status.Length-1] <= 6)) 
                return true;
            //if (
            //    (this.CmdTxObj.CurrentValue == E_CommandTx.HeatingOn) ||
            //    (this.CmdTxObj.CurrentValue == E_CommandTx.GeneralOn) ||
            //    (this.CmdTxObj.CurrentValue == E_CommandTx.CircuitBreakerOn))
            //    return true;
            else
                return false;
        }

        public bool GetAlarm(bool writeEnabled)
        {
            /*****************************************************
             * Checks to see if a request has been ignored and 
             * returns true if there is an alarm status
             *****************************************************/
            int alarmFaultCount = 5;
            int logFaultCount = 2;
            bool alarm = false;
            bool TxOn = false;
            
            if (GlobalStatusObj.CurrentValue == Convert.ToInt16(E_Status.transmitter_on)) TxOn = true;

            //Check each item in the dictionary
            foreach (var txitem in TxData)
            {
                if (txitem.Value.RequestValue != null)
                {
                    //Item has a Request value. Increment fault counter if Request Value != Current Value
                    if (txitem.Value.RequestValue != txitem.Value.CurrentValue)
                    {
                        //Increment fault counter
                        txitem.Value.FaultCount++;

                        //If Disable Alarm for unknown TX status is checked, we won't count faults
                        if (DisableUnknownStatusAlarm && GlobalStatusObj.CurrentValue == Convert.ToInt16(E_Status.unknown)) txitem.Value.FaultCount = 0;

                        //Upper bound to fixed value to prevent overflow
                        if (txitem.Value.FaultCount > alarmFaultCount) txitem.Value.FaultCount = alarmFaultCount + 1;

                        //Log discrepency, but limit number of entries.
                        if (txitem.Value.FaultCount >= logFaultCount && txitem.Value.FaultCount <= alarmFaultCount)
                        {
                            if (writeEnabled == true)
                            {
                                if (txitem.Value.ReadOnly == true)
                                {
                                    //Only log ActualPowerPercent error if TX is fully on.
                                    if (!(TxOn && (txitem.Key == "ActualPowerPercentObj")))
                                    {
                                        log.Write(string.Format("{0} Current: {1} Desired: {2} (Read Only)",
                                                        txitem.Value.Description,
                                                        txitem.Value.CurrentValue,
                                                        txitem.Value.RequestValue));
                                    }
                                }
                                else
                                {
                                    log.Write(string.Format("{0} Current: {1} Requested: {2} Try Count: {3}",
                                                    txitem.Value.Description,
                                                    txitem.Value.CurrentValue,
                                                    txitem.Value.RequestValue,
                                                    txitem.Value.FaultCount));
                                }
                            }
                        }

                        //If Fault count is above threshold, set alarm true
                        if (txitem.Value.FaultCount == alarmFaultCount)
                        {
                            alarm = true;
                            log.Write(string.Format("Alarm activated for {0}", txitem.Value.Description));
                        }
                    }
                    else
                    {
                        //Items match, there is no fault
                        txitem.Value.FaultCount = 0;
                    }
                    
                }
            }

            //Return the alarm status
            return alarm;
        }
		 
        public void SetSnmpIntegers()
        {
            // new Object list of items to be written
            List<Vb> setVbItems = new List<Vb>();

            //Add TxItems which need to be Set
            if (GetCurrentValue("OperatorObj") == "Remote")
            {
                foreach (var txitem in TxData)
                {
                    if (
                        (txitem.Value.RequestValue != null) //Item has a RequestValue
                        && (txitem.Value.RequestValue != txitem.Value.CurrentValue) //Current value does not match request
                        && (txitem.Value.ReadOnly == false) //Item is allowed to be written
                        )
                    {
                        //Add element to Snmp Set List
                        setVbItems.Add(new Vb(new Oid(txitem.Value.Oid), new Integer32(Convert.ToInt32(txitem.Value.RequestValue))));
                        log.Write(string.Format("{0} Current: {1} Requested: {2}", txitem.Value.Description, txitem.Value.CurrentValue.ToString(), txitem.Value.RequestValue.ToString()));
                    }
                }


                //Create SNMP connection to the IP address of this Transmitter
                SimpleSnmp snmp = new SimpleSnmp(this.IPaddress, "public");
                if (!snmp.Valid)
                {
                    log.Write(string.Format("SNMP agent host name/ip address ({0}) is invalid.", this.IPaddress));
                    //Disable further communication
                    //this.CommEnabled = false;
                    return;
                }

                //Execute SNMP Get and store results in new dictionary
                if (setVbItems.Count > 0)
                {
                    log.Write(string.Format("{0} Going to Write SNMP data now", TxNameObj.CurrentValue));

                    Dictionary<Oid, AsnType> result = snmp.Set(SnmpVersion.Ver2, setVbItems.ToArray());
                    if (result == null)
                    {
                        //Write log entry and show message box if data not received from SNMP Get
                        string msgtext = ("No Set results received from Transmitter. IP Address: " + this.IPaddress);
                        log.Write(msgtext);
                        //Disable further communication
                        //this.CommEnabled = false;
                        return;
                    }
                }
            }
        }

        public void GetSnmpStatus()
        {
            /*************************************************
            * SNMP Get Data Method
            *************************************************/
            
            //Create SNMP connection to the IP address of this Transmitter
            SimpleSnmp snmp = new SimpleSnmp(this.IPaddress, "public");
            if (!snmp.Valid)
            {
                if (this.CommEnabled == true)
                {
                    log.Write(string.Format("SNMP agent host name/ip address ({0}) is invalid.", this.IPaddress));
                }
                return;
            }

            //Create new string array of the OID's to get
            string[] getOids = TxData.Keys.ToArray();

            //Execute SNMP Get and store results in new dictionary
            Dictionary<Oid, AsnType> result = snmp.Get(SnmpVersion.Ver2, getOids);
            if (result == null)
            {
                //Write log entry and show message box if data not received from SNMP Get. Only write once until we have communication again.
                if (this.CommEnabled == true)
                {
                    string msgtext = string.Format("No Get results received from Transmitter IP Address: {0}", this.IPaddress);
                    log.Write(msgtext);
                    //Disable further communication
                    //this.CommEnabled = false;
                }
                return;
            }
            

            //Process the SNMP result and copy to the TxObject dictionary
            foreach (KeyValuePair<Oid, AsnType> kvp in result)
            {
                TxData["." + kvp.Key.ToString()].DataType = SnmpConstants.GetTypeName(kvp.Value.Type);
                TxData["." + kvp.Key.ToString()].GetResult = kvp.Value.ToString();
            }

            //Convert the SNMP GetResult (string) to the expected datatype
            convertSnmpData();
        }

        public string ReadStatusString(bool writeEnabled)
        {
            /********************************
             * returns a simple string that contains all data to be displayed on a single label in the GUI
             * ******************************/
            StringWriter status = new StringWriter();
            
            //if (GetAlarm(writeEnabled) == true)
            //{
            //    if (writeEnabled == true)
            //    {
            //        //If there are any ignored requests, print them to the GUI here
            //        status.WriteLine("\nError while sending requests! Check Log File");
            //    }
            //    else
            //    {
            //        status.WriteLine("\nPending Requests from PLC:");
            //    }

            //    //Add Pending data
            //    foreach (var txitem in TxData)
            //    {
            //        if (txitem.Value.FaultCount > 0)
            //        {
            //            if (    (writeEnabled == true) 
            //                &&  (txitem.Value.ReadOnly == false))
            //            {
            //                status.WriteLine("{0} Current: {1} Requested: {2} Fault Count: {3}",
            //                                        txitem.Value.Description,
            //                                        txitem.Value.CurrentValue,
            //                                        txitem.Value.RequestValue,
            //                                        txitem.Value.FaultCount);
            //            }
            //            else
            //            {
            //                status.WriteLine("{0} Current: {1} Requested: {2} (Read Only)",
            //                                     txitem.Value.Description,
            //                                     txitem.Value.CurrentValue,
            //                                     txitem.Value.RequestValue);
            //            }
            //        }
            //    }
            //}
            //else
            //{
                status.WriteLine("Current state: {0}", (E_Status)GlobalStatusObj.CurrentValue);
            //}


            return status.ToString();
        }

        private void convertSnmpData()        
        {
            /**************************************
             * Converts the SNMP result data to the expected data type defined in the declaration of each TxItem
             * Performs operation on the global TxItem dictionary
             * ************************************/
            //declare vars of each type to get correct conversion
            int testint = 0;
            string teststring = "0";
            E_CommandModulationMode testEnCommandModulationMode = E_CommandModulationMode.Unknown;
            E_CommandPower testEnCommandPower = E_CommandPower.Unknown;
            E_CommandTx testEnCommandTx = E_CommandTx.Unknown;
            E_Operator testEnOperator = E_Operator.Unknown;
            E_SwitchOverMode testEnSwitchOverMode = E_SwitchOverMode.Unknown;
            E_Status testStatus = E_Status.unknown;

            //Start debug log
            StreamWriter log = new StreamWriter("LogFile.txt", true);

            foreach (var txitem in TxData)
            {
                //log.WriteLine("Attempting to convert to type: {0} for item: {1}", txitem.Value.CurrentValue.GetType(), txitem.Value.Description);
                try 
                {
                        if (txitem.Value.CurrentValue.GetType() == teststring.GetType())
                        {
                            //Expected type is string - copy directly
                            txitem.Value.CurrentValue = txitem.Value.GetResult;
                        }
                        else if (txitem.Value.CurrentValue.GetType() == testint.GetType())
                        {
                            //Expected type is int - try to convert
                            txitem.Value.CurrentValue = Convert.ToInt32(txitem.Value.GetResult);
                        }
                        else if (txitem.Value.CurrentValue.GetType() == testEnCommandModulationMode.GetType())
                        {
                            //Expected type is enum - try to convert enum, then put enum text in GetResult
                            int enumvalue = Convert.ToInt32(txitem.Value.GetResult);
                            txitem.Value.CurrentValue = (E_CommandModulationMode)enumvalue;
                            txitem.Value.GetResult = ((E_CommandModulationMode)enumvalue).ToString();
                        }
                        else if (txitem.Value.CurrentValue.GetType() == testEnCommandPower.GetType())
                        {
                            //Expected type is enum - try to convert enum, then put enum text in GetResult
                            int enumvalue = Convert.ToInt32(txitem.Value.GetResult);
                            txitem.Value.CurrentValue = (E_CommandPower)enumvalue;
                            txitem.Value.GetResult = ((E_CommandPower)enumvalue).ToString();
                        }
                        else if (txitem.Value.CurrentValue.GetType() == testEnCommandTx.GetType())
                        {
                            //Expected type is enum - try to convert enum, then put enum text in GetResult
                            int enumvalue = Convert.ToInt32(txitem.Value.GetResult);
                            txitem.Value.CurrentValue = (E_CommandTx)enumvalue;
                            txitem.Value.GetResult = ((E_CommandTx)enumvalue).ToString();
                        }
                        else if (txitem.Value.CurrentValue.GetType() == testEnOperator.GetType())
                        {
                            //Expected type is enum - try to convert enum, then put enum text in GetResult
                            int enumvalue = Convert.ToInt32(txitem.Value.GetResult);
                            txitem.Value.CurrentValue = (E_Operator)enumvalue;
                            txitem.Value.GetResult = ((E_Operator)enumvalue).ToString();
                        }
                        else if (txitem.Value.CurrentValue.GetType() == testEnSwitchOverMode.GetType())
                        {
                            //Expected type is enum - try to convert enum, then put enum text in GetResult
                            int enumvalue = Convert.ToInt32(txitem.Value.GetResult);
                            txitem.Value.CurrentValue = (E_SwitchOverMode)enumvalue;
                            txitem.Value.GetResult = ((E_SwitchOverMode)enumvalue).ToString();
                        }
                        else if (txitem.Value.CurrentValue.GetType() == testStatus.GetType())
                        {
                            //Expected type is int - try to convert int
                            txitem.Value.CurrentValue = Convert.ToInt32(txitem.Value.GetResult);
                        }
                        else
                        {
                            log.WriteLine("Unable to convert SNMP data to expected type for item: {0}", txitem.Value.Description);
                        }
                }
                catch { log.WriteLine("Unable to convert SNMP data to expected type for item: {0} (catch statement)", txitem.Value.Description); }
            }

            //Close debug log
            log.Close();
        }

        public string GetCurrentValue(string key)
        {
            switch (key)
            {
                case "OperatorObj":
                    return Convert.ToString(OperatorObj.CurrentValue);
                case "SwitchOverModeObj":
                    return Convert.ToString(SwitchOverModeObj.CurrentValue);
                case "CmdTxObj":
                    return Convert.ToString(CmdTxObj.CurrentValue);
                case "GlobalStatusObj":
                    return Convert.ToString(GlobalStatusObj.CurrentValue);
                default:
                    return "NotFound";
            }
        }

        public string GetTxState(Timer tmrLogMeters)
        {
            string state = Convert.ToString((E_Status)GlobalStatusObj.CurrentValue);
            if (state != txState)
            {
                log.Write(string.Format("Tx state changed from {0} to {1}", txState, state));

                if (state == "transmitter_on")
                {
                     tmrLogMeters.Interval = 60000;
                     tmrLogMeters.Enabled = true;
                }
                else
                    tmrLogMeters.Enabled = false;
                txState = state;
            }
            return state;
        }

        public double[] MeterValues()
        {
            double[] Values = new double[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

            try
            {
                Values[0] = MeasAudioInputLevelObj.CurrentValue;
                Values[1] = MeasRfMainsVoltageObj.CurrentValue;
                Values[2] = MeasRfPowerObj.CurrentValue;
                Values[3] = MeasVSWRObj.CurrentValue * 0.01;
                Values[4] = MeasReflectedPowerObj.CurrentValue;
                Values[5] = MeasRfDifferentialTemperatureObj.CurrentValue * 0.1;
                Values[6] = MeasRfGridVoltageObj.CurrentValue;
                Values[7] = MeasRfGridCurrentObj.CurrentValue * 0.01;
                Values[8] = MeasRfAnodeVoltageObj.CurrentValue * 0.1;
                Values[9] = MeasRfAnodeCurrentObj.CurrentValue * 0.1;
                Values[10] = MeasRfScreenCurrentObj.CurrentValue * 0.01;
            }
            catch {  }
            return Values;
        }
    }

    class TxItem
    {
        public string Oid { get; set; }
        public string Description { get; set; }
        public dynamic CurrentValue { get; set; }
        public dynamic RequestValue { get; set; }
        public string GetResult { get; set; }
        public string DataType { get; set; }
        public int FaultCount { get; set; }
        public bool ReadOnly { get; set; }
    }
}
